package edu.pku.sei.modeler.uml.commands.timing;

import org.eclipse.draw2d.Bendpoint;
import org.eclipse.draw2d.XYAnchor;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.commands.Command;

import edu.pku.sei.modeler.editpolicies.TimeLineBendPointPolicy;
import edu.pku.sei.modeler.exceptions.FactoryNotFoundException;
import edu.pku.sei.modeler.model.common.ModelRegistry;
import edu.pku.sei.modeler.model.structure.MetaBendPoint;
import edu.pku.sei.modeler.model.structure.MetaLink;
import edu.pku.sei.modeler.model.structure.StructureFactory;

public class TimeLineAddBendPointCommand extends Command {
	private MetaLink link;
	private MetaBendPoint pointLeft;
	private MetaBendPoint pointRight;
	private int index = -1;
	private StructureFactory sFactory;
	private Point location;
	private Point leftBound;
	private Point rightBound;
	public TimeLineAddBendPointCommand(MetaLink link, Point location, int index, Point srcAnchor, Point dstAnchor) {
		super("Create Bendpoint");
		this.index = index;
		this.location = location;
		this.link = link; 
		
		
		if (index == 0)
			this.leftBound = srcAnchor;
		else this.leftBound = ((Bendpoint)link.getBendPoints().get(index-1)).getLocation();
		
		if (index == link.getBendPoints().size())
			this.rightBound = dstAnchor;
		else this.rightBound = ((Bendpoint)link.getBendPoints().get(index)).getLocation();
		location.x = (leftBound.x + rightBound.x)/2;
		try {
			sFactory = (StructureFactory)ModelRegistry.getRegistry().getStructureFactory(link.getModelElement().getModel());
			
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FactoryNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public boolean canExecute() {
		return link != null;
	}

	public void execute() {
		if (index == link.getBendPoints().size()
				|| rightBound.x - location.x > TimeLineBendPointPolicy.NEW_BENDPOINT_DISTANCE) {
			int x = (rightBound.x + location.x)/2;
			int y = rightBound.y;
			
			MetaBendPoint right1 = sFactory.createMetaBendPoint();
			right1.x = x - location.x < TimeLineBendPointPolicy.NEW_BENDPOINT_DISTANCE ? x : location.x + TimeLineBendPointPolicy.NEW_BENDPOINT_DISTANCE;
			right1.y = location.y;
			
			MetaBendPoint right2 = sFactory.createMetaBendPoint();
			right2.x = x - location.x < TimeLineBendPointPolicy.NEW_BENDPOINT_DISTANCE ? x : location.x + TimeLineBendPointPolicy.NEW_BENDPOINT_DISTANCE;
			right2.y = y;
			
			link.getBendPoints().add(index, right1);
			link.getBendPoints().add(index+1, right2);
		} else {
			MetaBendPoint right = (MetaBendPoint) link.getBendPoints().get(index);
			right.y = location.y;
		}
		
		if (index == 0 
				|| location.x - leftBound.x > TimeLineBendPointPolicy.NEW_BENDPOINT_DISTANCE) {
			int x = (leftBound.x + location.x)/2;
			int y = leftBound.y;
			
			MetaBendPoint left1 = sFactory.createMetaBendPoint();
			left1.x = location.x - x < TimeLineBendPointPolicy.NEW_BENDPOINT_DISTANCE ? x : location.x-TimeLineBendPointPolicy.NEW_BENDPOINT_DISTANCE;
			left1.y = location.y;
			
			MetaBendPoint left2 = sFactory.createMetaBendPoint();
			left2.x = location.x - x < TimeLineBendPointPolicy.NEW_BENDPOINT_DISTANCE ? x : location.x-TimeLineBendPointPolicy.NEW_BENDPOINT_DISTANCE;;
			left2.y = y;
			
			link.getBendPoints().add(index, left2);
			link.getBendPoints().add(index + 1, left1);
		} else {
			MetaBendPoint left = (MetaBendPoint) link.getBendPoints().get(index - 1);
			left.y = location.y;
		}
		
		
//		link.getBendPoints().add(index, point);
	}

	public void undo() {
		link.getBendPoints().remove(index);
	}
}
